package com.bestv.search.management.datasyn.spider;

import com.bestv.search.common.dataSource.DataSourceKey;
import com.bestv.search.common.dataSource.DataSourceKeyUtil;
import com.bestv.search.common.model.NetInfoReview;
import com.bestv.search.common.service.NetInfoReviewManager;
import com.bestv.search.common.util.StringConst;
import com.bestv.search.management.datasyn.spider.model.DouBanReviewJSON;
import com.bestv.search.management.datasyn.spider.model.DouBanVideoReviewJSON;
import org.hibernate.Hibernate;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

public class SpiderReviewsSyncer extends SpiderSyncer {

    private NetInfoReviewManager netInfoReviewManager;

    public SpiderReviewsSyncer() {
        super();
        setNetInfoReviewManager((NetInfoReviewManager) context.getBean("netInfoReviewManager"));
    }

    public void sync() {
        String syncMessage = null;
        try {
            status = getProgramSyncStatus(StringConst.DOUBAN, 1, StringConst.REVIEWS);
            Date syncSuccessDate = null;
            if (status != null) {
                syncSuccessDate = status.getSyncSuccessTime();
            }

            // Gets file path
            String filePath = getFileFullPath(StringConst.REVIEWS, StringConst.DOUBAN, syncSuccessDate,
                    StringConst.DOUBAN_ALL_VIDEOS_REVIEWS_FILE);
            if (filePath != null) {
                DouBanVideoReviewJSON revoewssJSON = new DouBanVideoReviewJSON();
                List<NetInfoReview> reviews = new ArrayList<NetInfoReview>();
                sync(reviews, revoewssJSON, filePath);
                syncMessage = "Success sync douban reviews from system search_spider @" + new Date();
            } else {
                syncMessage = "Doesn't find any new douban reviews in system search_spider @" + new Date();
            }
        } catch (Exception e) {
            syncMessage = "Failed sync douban reviews  from system search_spider @" + new Date();
            logger.error(syncMessage);
            logger.error(e);
        } finally {
            // Updates sync status
            updateSyncStatus(getSyncStatus(StringConst.DOUBAN, StringConst.REVIEWS, syncMessage));
        }
    }

    @SuppressWarnings("unchecked")
    @Override
    protected <T, K> T convert(K sourceObject, T destObject) {
        if (sourceObject != null) {
            List<NetInfoReview> reviews = new ArrayList<NetInfoReview>();
            DouBanVideoReviewJSON videoReviewsJSON = (DouBanVideoReviewJSON) sourceObject;
            for (DouBanReviewJSON reviewJSON : videoReviewsJSON.getReviews()) {
                NetInfoReview review = new NetInfoReview();
                review.setNetId(videoReviewsJSON.getId());
                review.setReviewId(reviewJSON.getId());
                review.setAuthor(reviewJSON.getAuthor());
                review.setContent(Hibernate.createBlob(reviewJSON.getText().getBytes()));
                review.setPublished(reviewJSON.getPublished());
                review.setTotalReviewed(reviewJSON.getTotal());
                review.setUsefulReviewed(reviewJSON.getUseful());
                review.setSource(StringConst.DOUBAN);
                review.setUpdateTime(new Date());
                reviews.add(review);
            }
            return (T) reviews;
        } else {
            return null;
        }
    }

    @Override
    protected <T, K> void saveOrUpdateToDB(K sourceObj, List<T> dbObj) {
        // local site code equals to local data source Key.
        String siteCode = systemCache.getLocalDataSourceKey();
        DataSourceKey key = DataSourceKeyUtil.convert(siteCode);

        @SuppressWarnings("unchecked")
        List<List<NetInfoReview>> list = (List<List<NetInfoReview>>) dbObj;
        List<NetInfoReview> listToSave = new ArrayList<NetInfoReview>();
        for (List<NetInfoReview> reviews : list) {
            listToSave.addAll(reviews);
        }
        netInfoReviewManager.saveOrUpdateList(key, listToSave);
    }

    public NetInfoReviewManager getNetInfoReviewManager() {
        return netInfoReviewManager;
    }

    public void setNetInfoReviewManager(NetInfoReviewManager netInfoReviewManager) {
        this.netInfoReviewManager = netInfoReviewManager;
    }
}